package auction

import auth.AuthBaseController

class AuctionController extends AuthBaseController {
	
	
	def beforeInterceptor = [action:this.&before,only:['delete', 'update', 'edit']]
	
	/**
	 * beforeInterceptor needs to be a wrapper that can be called without parameters.
	 * Grails would raise voodoo errors if hasPerms() was called directly from within
	 * the dictionary above
	 */
	def before = {
		// this prohibits manipulation of not-owned objects
		hasPerms(Auction, "user")
	}
	
	
    /**
    Die Erlaubte Methode zur Übertragung von Daten aus den Views an die Methoden 'save', 'update' und 'delete' dieses Controllers ist POST.
     */
	static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

	/**
	 * liefert alle Auktionen zurück die vom eingeloggten Nutzer angelegt wurden
	 */
	def showAuctions = {
		def auctionInstanceList = Auction.findAllByUser(session.user)
		if (!auctionInstanceList) {
			flash.message = "Keine Auktionen Verfügbar."
			redirect(controller: "userprofile", action: "showData")
		}
		else {
			[auctionInstanceList: auctionInstanceList]
		}
	}
	
	/**
	* Die Index-Methode leitet auf 'List' um
	*/
	def index = {
        redirect(action: "list", params: params)
    }
	

	/**
	* Die list-Methode leitet auf 'List' um
	*/
    def list = {
        params.max = Math.min(params.max ? params.int('max') : 10, 100)
        [auctionInstanceList: Auction.list(params), auctionInstanceTotal: Auction.count()]
    }

	/**
	* Die create-Methode legt eine neue Auction-Instanz an und übergibt die Parameter aus dem zugehörigen View
	* an diese Instanz.
	* @return AuctionInstance mit Properties
	*/
    def create = {
        def auctionInstance = new Auction()
        auctionInstance.properties = params
        return [auctionInstance: auctionInstance]
    }

	/**
	* Die save-Methode legt eine neue Auction-Instanz an und übergibt die Parameter aus dem zugehörigen View
	* an diese Instanz. Außerdem wird der Session-User sowie das aktuelle Datum an die Instanz angehangen.
	* Falls die Instanz gespeichert wurde, wird eine Nachricht ausgegeben und auf die show-methode umgeleitet.
	* Andernfalls wird die Instanz an den create-View übergeben und dieser aufgerufen.
	*/
    def save = {
		try{
			params.startprice = params.startprice.replace(",", ".").toFloat()
		}
		catch(e){
			flash.error = "Das ist keine gültige Zahl!"
		}
        def auctionInstance = new Auction(params)
		//use sessions user as user for new object
		auctionInstance.user = session.user
		//use date of creation as startDate
		auctionInstance.startDate = new Date()
		
		//handle uploaded file
		def uploadedFile = request.getFile('Datei')
		if(!uploadedFile.empty){
		  println "Class: ${uploadedFile.class}"
		  println "Name: ${uploadedFile.name}"
		  println "OriginalFileName: ${uploadedFile.originalFilename}"
		  println "Size: ${uploadedFile.size}"
		  println "ContentType: ${uploadedFile.contentType}"
	
		  def webRootDir = servletContext.getRealPath("/")
		  def actionDir = new File(webRootDir, "/bidhub/${session.user.login}")
		  actionDir.mkdirs()
		  uploadedFile.transferTo( new File( actionDir, uploadedFile.originalFilename))
		  auctionInstance.filename = uploadedFile.originalFilename
		}
			
		
		
        if (auctionInstance.save(flush: true)) {
            flash.message = "${message(code: 'default.created.message', args: [message(code: 'auction.label', default: 'Auction'), auctionInstance.id])}"
            redirect(action: "show", id: auctionInstance.id)
        }
        else {
            render(view: "create", model: [auctionInstance: auctionInstance])
        }
    }

	/**
	* Die show-Methode listet alle Auction-Instanzen nach ihrer ID.
	* Falls keine Auctionen vorhanden sind, wird eine Fehler-Nachricht ausgegeben und auf die list-Methode umgeleitet.
	* Andernfalls wird zur nächsten ID übergegangen.
	* @return AuctionInstance
	*/
    def show = {
        def auctionInstance = Auction.get(params.id)
        if (!auctionInstance) {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'auction.label', default: 'Auction'), params.id])}"
            redirect(action: "list")
        }
        else {
            [auctionInstance: auctionInstance]
        }
    }

	/**
	 * Abgelaufene Auktionen und Auktionen mit Geboten können nicht geändert werden
	 */
    def edit = {
        def auctionInstance = Auction.get(params.id)
        if (!auctionInstance) {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'auction.label', default: 'Auction'), params.id])}"
            redirect(action: "list")
        }
		else if(auctionInstance.endDate < new Date()){
			flash.message = "Die Auktion kann nach Auktionsende nicht mehr bearbeitet werden."
			redirect(action: "list")
		}
		else if(auctionInstance.bids){
			flash.message = "Die Auktion kann nicht mehr bearbeitet werden, wenn bereits Gebote vorliegen."
			redirect(action: "list")
		}
        else {
            return [auctionInstance: auctionInstance]
        }
    }

	/**
	* Die update-Methode ruft eine AuctioInstance mit ihrer ID auf.
	* Falls die Instanz abrufbar ist
	* 	Falls deren aktuelle Version neuer ist als die gespeicherte, wurde sie zwischenzeitlich von anderem User editiert. Dann wird die Instanz an
	* 	den edit-View übergeben und die Schleife beendet.
	* 	Falls die Instanz fehlerhaft abgespeichert ist, wird der show-view mit dieser Instanz aufgerufen.
	* 	Andernfalls wird die Instanz an den edit-View übergeben.
	* Andernfalls wird auf die list-Methode umgeleitet.
	*/
    def update = {
        def auctionInstance = Auction.get(params.id)
        if (auctionInstance) {
            if (params.version) {
                def version = params.version.toLong()
                if (auctionInstance.version > version) {
                    
                    auctionInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'auction.label', default: 'Auction')] as Object[], "Another user has updated this Auction while you were editing")
                    render(view: "edit", model: [auctionInstance: auctionInstance])
                    return
                }
            }
            auctionInstance.properties = params
            if (!auctionInstance.hasErrors() && auctionInstance.save(flush: true)) {
                flash.message = "${message(code: 'default.updated.message', args: [message(code: 'auction.label', default: 'Auction'), auctionInstance.id])}"
                redirect(action: "show", id: auctionInstance.id)
            }
            else {
                render(view: "edit", model: [auctionInstance: auctionInstance])
            }
        }
        else {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'auction.label', default: 'Auction'), params.id])}"
            redirect(action: "list")
        }
    }

	/**
	* Die delete-Methode versucht die Instanz aufzurufen. Falls diese vorhanden ist, wird probiert sie zu löschen. Fehler werden dabei über eine
	* Nachricht aufgefangen. Beim erfolgreichen Löschen wird auf die list-Methode umgeleitet, bei nicht-Erfolg wird die Instanz an den show-View
	* übergeben.
	* Falls die Instanz nicht aufgerufen werden kann, wird auf die list-Methode umgeleitet.
	* Abgelaufene Auktionen und Auktionen mit Geboten können nicht gelöscht werden!
	*/
    def delete = {
        def auctionInstance = Auction.get(params.id)
        if (auctionInstance) {
			
			if(auctionInstance.endDate < new Date()){
				flash.message = "Die Auktion kann nach Auktionsende nicht mehr gelöscht werden."
				redirect(action: "list")
			}
			else if(auctionInstance.bids){
				flash.message = "Die Auktion kann nicht mehr gelöscht werden, wenn bereits Gebote vorliegen."
				redirect(action: "list")
			}
			else {
				try {
					auctionInstance.delete(flush: true)
					flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'auction.label', default: 'Auction'), params.id])}"
					redirect(action: "list")
				}
				catch (org.springframework.dao.DataIntegrityViolationException e) {
					flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'auction.label', default: 'Auction'), params.id])}"
					redirect(action: "show", id: params.id)
				}				
			}
        }
        else {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'auction.label', default: 'Auction'), params.id])}"
            redirect(action: "list")
        }
    }
}
